package com.example.mycarcalling.fragment;

import android.content.Intent;
import android.graphics.Color;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.databinding.DataBindingUtil;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;

import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.location.Poi;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.InfoWindow;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.model.LatLng;
import com.example.lib_cache.viewmodel.MapFragmentViewModel;
import com.example.lib_common.base.BaseFragment;
import com.example.lib_common.util.LiveDataManager;
import com.example.lib_common.util.MyOrientationListener;
import com.example.lib_common.util.SpUtils;
import com.example.mycarcalling.R;
import com.example.mycarcalling.activity.EndActivity;
import com.example.mycarcalling.activity.NavSettlementDialog;
import com.example.mycarcalling.activity.PickUpActivity;
import com.example.mycarcalling.activity.RoutePlanActivity;
import com.example.mycarcalling.activity.StartActivity;
import com.example.mycarcalling.activity.TravelActivity;
import com.example.mycarcalling.activity.WaitingActivity;
import com.example.mycarcalling.databinding.FragmentMapBinding;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;


/**
 * 地图
 */
public class MapFragment extends BaseFragment{

    private FragmentMapBinding fragmentMapBinding;
    private MapFragmentViewModel mapFragmentViewModel;

    private BitmapDescriptor mBitmapDescriptor =
            BitmapDescriptorFactory.fromResource(R.mipmap.icon_gcoding);


    private MapView mapView = null;
    private BaiduMap baiduMap = null;

    //类的对象
    private MyOrientationListener myOrientationListener;
    //接受方向角
    private float mCurrentAccuracy;
    private float mXDirection;
    private double mCurrentLatitude;
    private double mCurrentLongitude;

    private MyLocationConfiguration configuration;

    private volatile boolean isFristLocation = true;

    private LocationClient mLocationClient = null;
    private MyLocationListener myLocationListener = null;
    private MyLocationConfiguration.LocationMode locationMode = MyLocationConfiguration.LocationMode.FOLLOWING;

    private NavSettlementDialog navSettlementDialog = null;


    private static final int REQUEST_NV_OPTIONS = 0;
    private static final int REQUEST_ROUTEPLAN = 1;
    private static final int REQUEST_WAITING = 2;
    private static final int REQUEST_PICKUP = 3;
    private static final int REQUEST_TRAVEL = 4;


    public final static String TAG = MapFragment.class.getSimpleName();

    @Override
    protected int getLayoutRes() {
        return R.layout.fragment_map;
    }


    private  void initData(){
        //创建数据源
        //创建一个ViewModel的工厂
        ViewModelProvider.Factory factory = ViewModelProvider.
                AndroidViewModelFactory.getInstance(getActivity().getApplication());
        //创建ViewModel的管理对象
        ViewModelProvider viewModelProvider = new ViewModelProvider(this,factory);
        //生产ViewModel
         mapFragmentViewModel= viewModelProvider.
                get(MapFragmentViewModel.class);


    }

    @Override
    protected void initView() {

        fragmentMapBinding = DataBindingUtil.bind(view.getRootView());
        fragmentMapBinding.setLifecycleOwner(this);

        mapView = fragmentMapBinding.bmapView;

        baiduMap = mapView.getMap();

        baiduMap.setTrafficEnabled(true);
        baiduMap.setMapStatus(MapStatusUpdateFactory.zoomTo(20));
        navSettlementDialog = new NavSettlementDialog(view.getContext());

        //开启定位
        baiduMap.setMyLocationEnabled(true);



        //定位初始化
        mLocationClient = new LocationClient(getContext());

        initData();

        initOrientation();
        initLocationOption();
        initListener();
        initObserve();



    }

    private void initObserve() {
        mapFragmentViewModel.getIsTransform().observe(this, new Observer<Boolean>() {
            @Override
            public void onChanged(Boolean aBoolean) {
                if(aBoolean){
                    navSettlementDialog.getTvDistance().setText(
                            mapFragmentViewModel.getDistance());
                    navSettlementDialog.getTvDistanceUnit().setText(
                            mapFragmentViewModel.getDistanceUnit());
                    navSettlementDialog.getTvDuration().setText(
                            mapFragmentViewModel.getDuration());
                    navSettlementDialog.show();

                }
            }
        });
    }

    private void initListener(){


        baiduMap.setOnMapStatusChangeListener(new BaiduMap.OnMapStatusChangeListener() {
            @Override
            public void onMapStatusChangeStart(MapStatus mapStatus) {

            }

            @Override
            public void onMapStatusChangeStart(MapStatus mapStatus, int i) {

            }

            @Override
            public void onMapStatusChange(MapStatus mapStatus) {

            }

            @Override
            public void onMapStatusChangeFinish(MapStatus mapStatus) {

            }
        });

        fragmentMapBinding.llConfirmStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getContext(), StartActivity.class);
                startActivityForResult(intent,REQUEST_NV_OPTIONS);
            }
        });

        fragmentMapBinding.tvEnd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getContext(), EndActivity.class);
                startActivityForResult(intent,REQUEST_NV_OPTIONS);
            }
        });
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode == 0) {
            if (resultCode == 1) {
                addMarkerToMap();
            }
            if (resultCode == 2) {
                mapFragmentViewModel.getEndPoiInfo();
                String endPoiName = mapFragmentViewModel.getEndPoiMutableLiveData()
                        .getValue().getPoiName();
                if (endPoiName.length() >= 8) {
                    fragmentMapBinding.tvEnd.setTextSize(20);
                } else {
                    fragmentMapBinding.tvEnd.setTextSize(30);
                }

                fragmentMapBinding.tvEnd.setText(
                        mapFragmentViewModel.getEndPoiMutableLiveData().getValue().getPoiName());

                if (LiveDataManager.getInstance().isContainKey("PoiInfo")
                        && LiveDataManager.getInstance().isContainKey("EndPoiInfo")) {
                    Intent intent = new Intent(getContext(), RoutePlanActivity.class);
                    startActivityForResult(intent,REQUEST_ROUTEPLAN);

                }
            }
        }
        if (requestCode == REQUEST_ROUTEPLAN){
            if(resultCode == 1){
                Intent intent = new Intent(view.getContext(), WaitingActivity.class);
                startActivityForResult(intent,REQUEST_WAITING);
            }
        }
        if(requestCode == REQUEST_WAITING){
            if(resultCode == 1){
                Intent intent = new Intent(view.getContext(), PickUpActivity.class);
                startActivityForResult(intent,REQUEST_PICKUP);

            }
        }
        if(requestCode == REQUEST_PICKUP){
            if(resultCode == 1){
                //打开新的导航页
                Intent intent = new Intent(view.getContext(), TravelActivity.class);
                startActivityForResult(intent,REQUEST_TRAVEL);
            }
        }
        if(requestCode == REQUEST_TRAVEL){
            if(resultCode == 1){
                //结算
                DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date date = new Date(System.currentTimeMillis());
                String thisTime = simpleDateFormat.format(date);
                String lastTime = SpUtils.getString(view.getContext(),"lastTime");

                mapFragmentViewModel.transformTime(lastTime,thisTime);

            }
        }

    }




    /**
     * 自定义上车点添加到地图上
     */
    private void addMarkerToMap() {
        Log.d("添加到地图","1111");

        if (baiduMap == null) {
            return;
        }
        baiduMap.clear();

        mapFragmentViewModel.getPoiInfo();

        TextView textView = new TextView(getActivity().getApplicationContext());
        textView.setText(mapFragmentViewModel.getPoiMutableLiveData().getValue().getPoiName());
        textView.setBackgroundColor(Color.WHITE);
        InfoWindow infoWindow = new InfoWindow(
                textView,
                mapFragmentViewModel.getPoiMutableLiveData().getValue().getLatLng(),
                -47);
        MarkerOptions markerOptions = new MarkerOptions();
        markerOptions.icon(mBitmapDescriptor)
                .position(mapFragmentViewModel.getPoiMutableLiveData().getValue().getLatLng())
                .scaleX(0.5f).scaleY(0.5f).infoWindow(infoWindow);
        baiduMap.addOverlay(markerOptions);

    }





    @Override
    public void onResume() {
        mapView.onResume();
        super.onResume();
    }

    @Override
    public void onPause() {
        mapView.onPause();
        super.onPause();
    }

    @Override
    public void onDestroy() {
        mLocationClient.stop();
        baiduMap.setMyLocationEnabled(false);
        mapView.onDestroy();
        mapView = null;
        super.onDestroy();
    }

    @Override
    public void onStop()
    {
        // 关闭图层定位
        baiduMap.setMyLocationEnabled(false);
        mLocationClient.stop();

        // 关闭方向传感器
        myOrientationListener.stop();
        super.onStop();
    }

    /**
     * 实现定位回调
     */
    public class MyLocationListener extends BDAbstractLocationListener {
        @Override
        public void onReceiveLocation(BDLocation location) {
            //此处的BDLocation为定位结果信息类，通过它的各种get方法可获取定位相关的全部结果
            //以下只列举部分获取经纬度相关（常用）的结果信息
            //更多结果信息获取说明，请参照类参考中BDLocation类中的说明

            //获取纬度信息
            double latitude = location.getLatitude();
            //获取经度信息
            double longitude = location.getLongitude();
            //获取定位精度，默认值为0.0f
            float radius = location.getRadius();
            //获取经纬度坐标类型，以LocationClientOption中设置过的坐标类型为准
            String coorType = location.getCoorType();
            //获取定位类型、定位错误返回码，具体信息可参照类参考中BDLocation类中的说明
            int errorCode = location.getLocType();

            //mapView 销毁后不在处理新接收的位置
            if (location == null || mapView == null) {
                return;
            }


            MyLocationData locData = new MyLocationData.Builder()
                    .accuracy(location.getRadius())
                    // 此处设置开发者获取到的方向信息，顺时针0-360
                    .direction(mXDirection)
                    .latitude(location.getLatitude())
                    .longitude(location.getLongitude())
                    .build();
            mCurrentAccuracy = location.getRadius();
            // 设置定位数据
            baiduMap.setMyLocationData(locData);
            mCurrentLatitude = location.getLatitude();
            mCurrentLongitude = location.getLongitude();


            //配置定位图层显示方式,三个参数的构造器
            /**
             * 1.定位图层显示模式
             * 2.是否允许显示方向信息
             * 3.用户自定义定位图标
             * */
            configuration = new MyLocationConfiguration(locationMode, true, null);
            //设置定位图层配置信息，只有先允许定位图层后设置定位图层配置信息才会生效，参见 setMyLocationEnabled(boolean)
            baiduMap.setMyLocationConfiguration(configuration);




            Log.d("当前坐标：" ,location.getAddrStr());
            Log.d("当前坐标：" ,location.getLocationDescribe());

//            Address address = new Address();
//            address.setLocationDescribe(location.getLocationDescribe());
            mapFragmentViewModel.refreshLocation(location);
            fragmentMapBinding.setMapViewModel(mapFragmentViewModel);

            if (isFristLocation) {
                isFristLocation = false;
                LatLng ll = new LatLng(location.getLatitude(),
                        location.getLongitude());

                MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(ll);
                Log.d("改变的Latlng：",ll.toString());
                baiduMap.animateMapStatus(u);
            }

        }
    }


    /**
     * 初始化定位参数配置
     */

    private void initLocationOption() {
        //定位服务的客户端。宿主程序在客户端声明此类，并调用，目前只支持在主线程中启动
        mLocationClient = new LocationClient(getContext());
        //声明LocationClient类实例并配置定位参数
        LocationClientOption locationOption = new LocationClientOption();
        myLocationListener = new MyLocationListener();
        //注册监听函数
        mLocationClient.registerLocationListener(myLocationListener);
        //可选，默认高精度，设置定位模式，高精度，低功耗，仅设备
        locationOption.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
        //可选，默认gcj02，设置返回的定位结果坐标系，如果配合百度地图使用，建议设置为bd09ll;
        locationOption.setCoorType("BD09LL");
        //可选，默认0，即仅定位一次，设置发起连续定位请求的间隔需要大于等于1000ms才是有效的
        locationOption.setScanSpan(1000);
        //可选，设置是否需要地址信息，默认不需要
        locationOption.setIsNeedAddress(true);
        //可选，设置是否需要地址描述
        locationOption.setIsNeedLocationDescribe(true);
        //可选，设置是否需要设备方向结果
        locationOption.setNeedDeviceDirect(false);
        //可选，默认false，设置是否当gps有效时按照1S1次频率输出GPS结果
        locationOption.setLocationNotify(true);
        //可选，默认true，定位SDK内部是一个SERVICE，并放到了独立进程，设置是否在stop的时候杀死这个进程，默认不杀死
        locationOption.setIgnoreKillProcess(true);
        //可选，默认false，设置是否需要位置语义化结果，可以在BDLocation.getLocationDescribe里得到，结果类似于“在北京天安门附近”
        locationOption.setIsNeedLocationDescribe(true);
        //可选，默认false，设置是否需要POI结果，可以在BDLocation.getPoiList里得到
        locationOption.setIsNeedLocationPoiList(true);
        //可选，默认false，设置是否收集CRASH信息，默认收集
        locationOption.SetIgnoreCacheException(false);
        //可选，默认false，设置是否开启Gps定位
        locationOption.setOpenGps(true);
        //可选，默认false，设置定位时是否需要海拔信息，默认不需要，除基础定位版本都可用
        locationOption.setIsNeedAltitude(false);
        //设置打开自动回调位置模式，该开关打开后，期间只要定位SDK检测到位置变化就会主动回调给开发者，该模式下开发者无需再关心定位间隔是多少，定位SDK本身发现位置变化就会及时回调给开发者
        locationOption.setOpenAutoNotifyMode();
        //设置打开自动回调位置模式，该开关打开后，期间只要定位SDK检测到位置变化就会主动回调给开发者
        locationOption.setOpenAutoNotifyMode(3000,1, LocationClientOption.LOC_SENSITIVITY_HIGHT);

        //需将配置好的LocationClientOption对象，通过setLocOption方法传递给LocationClient对象使用
        mLocationClient.setLocOption(locationOption);
        //开始定位
        mLocationClient.start();
    }

    private void initOrientation() {
        //传感器
        myOrientationListener = new MyOrientationListener(getContext());
        myOrientationListener
                .setOnOrientationListener(new MyOrientationListener.OnOrientationListener() {
                    @Override
                    public void onOrientationChanged(float x) {
                        mXDirection = (int) x;

                        // 构造定位数据

                        MyLocationData locData = new MyLocationData.Builder()
                                .accuracy(mCurrentAccuracy)
                                // 此处设置开发者获取到的方向信息，顺时针0-360
                                .direction(mXDirection)
                                .latitude(mCurrentLatitude)
                                .longitude(mCurrentLongitude)
                                .build();
                        // 设置定位数据
                        baiduMap.setMyLocationData(locData);
                        // 设置自定义图标

                        setConfiguration();
                    }
                });
        myOrientationListener.start();
    }


    private void setConfiguration() {
        configuration = new MyLocationConfiguration(locationMode,
                true, null);
        baiduMap.setMyLocationConfiguration(configuration);
    }
}
